package com.ruoyi.energy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.core.exception.CustomException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.energy.domain.NyCheckSum;
import com.ruoyi.energy.domain.NyMeterAccount1;
import com.ruoyi.energy.domain.NyMeterAccount2;
import com.ruoyi.energy.domain.vo.NyCheckMerBPVO;
import com.ruoyi.energy.domain.vo.NyCheckSumVO;
import com.ruoyi.energy.domain.vo.NyMeterAccountVO;
import com.ruoyi.energy.mapper.NyCheckMeterMapper;
import com.ruoyi.energy.mapper.NyCheckSumMapper;
import com.ruoyi.energy.mapper.NyMeterAccount1Mapper;
import com.ruoyi.energy.mapper.NyMeterAccount2Mapper;
import com.ruoyi.energy.service.INyCheckMeterService;
import com.ruoyi.energy.service.INyCheckSumService;
import com.ruoyi.energy.service.INyMeterAccount2Service;
import com.ruoyi.energy.service.manager.NyMeterAccountManager;
import com.ruoyi.omp.api.domain.NyCheckMeter;
import com.ruoyi.omp.api.domain.vo.NyCheckMeterVO;
import com.ruoyi.omp.api.enums.NyMeterCategoryEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

//import org.mybatis.logging.Logger;

/**
 * 抄表录入Service业务层处理
 *
 * @author cjie
 * @date 2021-07-29
 */
@Service
public class NyCheckMeterServiceImpl implements INyCheckMeterService {

    private static final Logger log = LoggerFactory.getLogger(NyCheckMeterServiceImpl.class);
    @Autowired
    private NyCheckMeterMapper nyCheckMeterMapper;

    @Autowired
    private NyMeterAccount1Mapper nyMeterAccount1Mapper;

    @Autowired
    private NyMeterAccount2Mapper nyMeterAccount2Mapper;

    @Autowired
    private NyCheckSumMapper nyCheckSumMapper;

    @Autowired
    private INyCheckSumService nyCheckSumService;

    @Autowired
    private INyMeterAccount2Service nyMeterAccount2Service;

    @Autowired
    private NyMeterAccountManager nyMeterAccountManager;

    /**
     * 查询抄表录入
     *
     * @param id 抄表录入ID
     * @return 抄表录入
     */
    @Override
    public NyCheckMeter selectNyCheckMeterById(String id) {
        return nyCheckMeterMapper.selectNyCheckMeterById(id);
    }

    /**
     * 查询抄表录入列表
     *
     * @param nyCheckMeter 抄表录入
     * @return 抄表录入
     */
    @Override
    public List<NyCheckMeter> selectNyCheckMeterList(NyCheckMeter nyCheckMeter) {
        return nyCheckMeterMapper.selectNyCheckMeterList(nyCheckMeter);
    }

    /**
     * 新增抄表录入
     *
     * @param nyCheckMeter 抄表录入
     * @return 结果
     */
    @Override
    public int insertNyCheckMeter(NyCheckMeter nyCheckMeter) {
        // 更新表台账2,当前度数。
        if (nyCheckMeter.getCurrentValue() != null) {
            NyMeterAccount2 account = new NyMeterAccount2();
            account.setId(nyCheckMeter.getMeterId());
            account.setCurrentValue(nyCheckMeter.getCurrentValue());
            account.setCurrentCheckDate(nyCheckMeter.getCurrentCheckDate());
            account.setMaxValue(nyCheckMeter.getMaxValue());
            account.setOverMax(nyCheckMeter.getOverMax());
            nyMeterAccount2Mapper.updateNyMeterAccount2(account);
        }
        //根据费用周期，meterId，meterNum调用
        NyCheckMeter search= new NyCheckMeter();
        search.setMeterId(nyCheckMeter.getMeterId());
        search.setMeterNum(nyCheckMeter.getMeterNum());
        if(nyCheckMeter.getFeeCycle() == null){
            try {
                search.setFeeCycle(DateUtils.getFirstDayOfMonth());
                nyCheckMeter.setFeeCycle(DateUtils.getFirstDayOfMonth());
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }else {
            search.setFeeCycle(nyCheckMeter.getFeeCycle());
        }

        List<NyCheckMeter> isexist = nyCheckMeterMapper.selectNyCheckMeterList(search);
        if(isexist.size()>0){
            nyCheckMeter.setId(isexist.get(0).getId());
            nyCheckMeter.setActualDosage(computeActualDosage(nyCheckMeter));
            return nyCheckMeterMapper.updateNyCheckMeter(nyCheckMeter);
        }else {
            nyCheckMeter.setId(IdUtil.getSnowflake(0, 0).nextIdStr());
            nyCheckMeter.setCreateTime(DateUtils.getNowDate());
            nyCheckMeter.setCreateBy(SecurityUtils.getUsername());
            nyCheckMeter.setActualDosage(computeActualDosage(nyCheckMeter));
            return nyCheckMeterMapper.insertNyCheckMeter(nyCheckMeter);
        }

    }

    /**
     * 修改抄表录入
     *
     * @param nyCheckMeter 抄表录入
     * @return 结果
     */
    @Override
    public int updateNyCheckMeter(NyCheckMeter nyCheckMeter) {
        nyCheckMeter.setUpdateTime(DateUtils.getNowDate());
        nyCheckMeter.setUpdateBy(SecurityUtils.getUsername());
        if (nyCheckMeter.getCurrentValue() != null) {
            NyMeterAccount2 account = new NyMeterAccount2();
            account.setId(nyCheckMeter.getMeterId());
            account.setCurrentValue(nyCheckMeter.getCurrentValue());
            account.setCurrentCheckDate(nyCheckMeter.getCurrentCheckDate());
            if(nyCheckMeter.getShareInitialValue() != null){
                account.setShareInitialValue(nyCheckMeter.getShareInitialValue());
            }

            nyMeterAccount2Mapper.updateNyMeterAccount2(account);
            nyCheckMeter.setActualDosage(computeActualDosage(nyCheckMeter));
        }
        return nyCheckMeterMapper.updateNyCheckMeter(nyCheckMeter);
    }

    private BigDecimal computeActualDosage(NyCheckMeter nyCheckMeter){
        BigDecimal result=BigDecimal.ZERO;
        if(nyCheckMeter.getMeterType().equals("水表")){
            //水表度数改为正数
            result = nyCheckMeter.getCurrentValue().subtract(nyCheckMeter.getLastValue()).abs();
        }else if(nyCheckMeter.getMeterType().equals("电表")){
            //电表实际度数，与max_value进行比较
            result = nyCheckMeter.getCurrentValue().subtract(nyCheckMeter.getLastValue());
            if(result.compareTo(BigDecimal.ZERO)<0){
                result = result.add(nyCheckMeter.getMaxValue());
            }
            if(nyCheckMeter.getMagnification() ==null){
                NyMeterAccount1 account = nyMeterAccount1Mapper.selectNyMeterAccount1ById(nyCheckMeter.getMeterId());
                nyCheckMeter.setMagnification(account.getMagnification());
            }
            result = result.multiply(nyCheckMeter.getMagnification());
        }
        return result;
    }

    /**
     * 批量删除抄表录入
     *
     * @param ids 需要删除的抄表录入ID
     * @return 结果
     */
    @Override
    public int deleteNyCheckMeterByIds(String[] ids) {
        return nyCheckMeterMapper.deleteNyCheckMeterByIds(ids);
    }

    /**
     * 删除抄表录入信息
     *
     * @param id 抄表录入ID
     * @return 结果
     */
    @Override
    public int deleteNyCheckMeterById(String id) {
        return nyCheckMeterMapper.deleteNyCheckMeterById(id);
    }

//    @Override
//    public NyCheckMeterWXVO selectWXNyCheckMeterById(String id) {
////        已经过时
//        return nyCheckMeterMapper.selectWXNyCheckMeterById(id);
//    }

    @Override
    public String importNyCheckMeter(List<NyCheckMeter> checkMeters) {
        if (StringUtils.isNull(checkMeters) || checkMeters.size() == 0) {
            throw new CustomException("导入抄表数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (NyCheckMeter checkMeter : checkMeters) {
            try {
                this.insertNyCheckMeter(checkMeter);
                successNum++;
                successMsg.append("<br/>" + successNum + "、抄表记录 " + checkMeter.getMeterNum() + checkMeter.getFeeCycle() + " 导入成功");
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、抄表记录 " + checkMeter.getMeterNum() + checkMeter.getFeeCycle() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new CustomException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public List<NyCheckMeter> genImportTemplate(NyCheckMeter nyCheckMeter) {
        List<NyCheckMeter> checkMeters = new ArrayList<>();
        //根据表类型，查询台账表
        NyMeterAccount1 account1 = new NyMeterAccount1();
        account1.setMeterType(nyCheckMeter.getMeterType());
        List<NyMeterAccount1> meterAccounts = nyMeterAccount1Mapper.selectNyMeterAccount1List(account1);
        //根据台账信息，查询抄表集合，为空，上期度数为初始化值，不空取第一个
        //查询抄表条件
        NyCheckMeter checkMeter = new NyCheckMeter();
        //查询抄表结果
        List<NyCheckMeter> nyCheckMeters = null;
        //导入抄表记录
        NyCheckMeter importCheckMeter = null;
        for (NyMeterAccount1 meter : meterAccounts) {
            checkMeter.setMeterId(meter.getId());
            nyCheckMeters = nyCheckMeterMapper.selectNyCheckMeterList(checkMeter);
            importCheckMeter = new NyCheckMeter();
            importCheckMeter.setMeterId(meter.getId());
            importCheckMeter.setMeterNum(meter.getMeterNum());
            importCheckMeter.setMeterType(meter.getMeterType());
            //上期度数
            if (nyCheckMeters == null || nyCheckMeters.size() == 0) {
                importCheckMeter.setLastCheckDate(meter.getCreateTime());
                importCheckMeter.setLastValue(meter.getInitialValue());
            } else {
                importCheckMeter.setLastCheckDate(nyCheckMeters.get(0).getCurrentCheckDate());
                importCheckMeter.setLastValue(nyCheckMeters.get(0).getCurrentValue());
            }
            checkMeters.add(importCheckMeter);
        }
        return checkMeters;
    }

    /*
    @Params feeCycle，meterType,parkNum，
   //分两次单表查询，组装数据
     */
    @Override
    public List<NyCheckMeterVO> selectCheckMeterList(NyCheckMeter checkMeter) {

        List<NyCheckMeterVO> results = new ArrayList<NyCheckMeterVO>();
        //查询总表,meterType，category，parkNum，enterpriseName
        NyMeterAccount2 nyMeterAccount2 = new NyMeterAccount2();
        nyMeterAccount2.setCategory(NyMeterCategoryEnum.总表.getCode());
        nyMeterAccount2.setMeterType(checkMeter.getMeterType());
        nyMeterAccount2.setParkNum(checkMeter.getParkNum());
        List<NyMeterAccount2> nyMeterAccounts = nyMeterAccount2Mapper.selectNyMeterAccount2List(nyMeterAccount2);
        //遍历总表，查询总表记录
        for(NyMeterAccount2 nma:nyMeterAccounts){
            NyCheckMeterVO result = new NyCheckMeterVO();
            result.setFeeCycle(checkMeter.getFeeCycle());
            //总表抄表记录
            NyCheckMeter nyCheckMeter = new NyCheckMeter();
            nyCheckMeter.setMeterId(nma.getId());
            nyCheckMeter.setFeeCycle(checkMeter.getFeeCycle());
            NyCheckMeter sumNyCheckMeter = nyCheckMeterMapper.selectNyCheckMeterVO(nyCheckMeter);
            if(sumNyCheckMeter == null){
                BeanUtils.copyBeanProp(result,nma);
                result.setMeterId(nma.getId());
                result.setFeeCycle(checkMeter.getFeeCycle());
            }else{
                BeanUtils.copyBeanProp(result,sumNyCheckMeter);
                result.setCheckMaterId(sumNyCheckMeter.getId());
            }
            result.setMeterName(nma.getMeterName());
            result.setMeterNum(nma.getMeterNum());
            results.add(result);
        }
        return results;
    }

    /*
    @Params feeCycle，meterType,parkNum，
    //分两次单表查询，组装数据
    return 总表抄表记录{私表抄表记录}
    */
    @Override
    public List<NyCheckMeterVO> selectCheckMeterSumAndPrivateList(NyCheckMeter checkMeter) {

        List<NyCheckMeterVO> results = new ArrayList<NyCheckMeterVO>();
        //查询总表,meterType，category，parkNum，enterpriseName
        NyMeterAccount2 nyMeterAccount2 = new NyMeterAccount2();
        nyMeterAccount2.setCategory(NyMeterCategoryEnum.总表.getCode());
        nyMeterAccount2.setMeterType(checkMeter.getMeterType());
        nyMeterAccount2.setParkNum(checkMeter.getParkNum());
        List<NyMeterAccount2> nyMeterAccounts = nyMeterAccount2Mapper.selectNyMeterAccount2List(nyMeterAccount2);

        Date feeCycle = checkMeter.getFeeCycle();
        //遍历总表，构建总表树
        for(NyMeterAccount2 nma:nyMeterAccounts){
            NyCheckMeterVO result = new NyCheckMeterVO();
            results.add(result);
            //查询总表抄表记录
            NyCheckMeter sumNyCheckMeter = this.selectNyCheckMeterByIdAndFeeCycle(nma.getId(),feeCycle);
            if(sumNyCheckMeter == null){
                BeanUtils.copyBeanProp(result,nma);
                result.setMeterId(nma.getId());
                result.setFeeCycle(checkMeter.getFeeCycle());
                continue;
            }else{
                BeanUtils.copyBeanProp(result,sumNyCheckMeter);
                result.setCheckMaterId(sumNyCheckMeter.getId());
            }
            //查询总表树下的私表
            NyMeterAccountVO accountVO = nyMeterAccountManager.selectRoot(nma.getId());
            List<NyMeterAccountVO> privateMeterList = nyMeterAccountManager.selectPrivateLeafs(accountVO);
            //查询私表抄表记录
            if(privateMeterList !=null && privateMeterList.size()>0){
                for(NyMeterAccountVO privateMeter:privateMeterList){
                    NyCheckMeterVO priva = new NyCheckMeterVO();
                    //私表抄表记录
                    NyCheckMeter privNyCheckMeter = this.selectNyCheckMeterByIdAndFeeCycle(privateMeter.getId(),feeCycle);
                    if(privNyCheckMeter != null ){
                        BeanUtils.copyBeanProp(priva,privNyCheckMeter);
                        priva.setCheckMaterId(privNyCheckMeter.getId());
                    }else {
                        BeanUtils.copyBeanProp(priva,privateMeter);
                        priva.setMeterId(privateMeter.getId());
                        priva.setFeeCycle(checkMeter.getFeeCycle());
                    }
                    result.getChildren().add(priva);
                }
            }
        }
        return results;
    }

    @Override
    public NyCheckMeter selectNyCheckMeterByIdAndFeeCycle(String meterId,Date feeCycle){
        NyCheckMeter result = null;
        NyCheckMeter nyCheckMeter1 = new NyCheckMeter();
        nyCheckMeter1.setMeterId(meterId);
        nyCheckMeter1.setFeeCycle(feeCycle);
        List<NyCheckMeter> nyCheckMeters= nyCheckMeterMapper.selectNyCheckMeterList(nyCheckMeter1);
        if(nyCheckMeters !=null && nyCheckMeters.size()>0){
            result = nyCheckMeters.get(0);
        }else {
            log.error("meterId: " + meterId + ",feeCycle:" + DateUtils.parseDateToStr(DateUtils.YYYY_MM,feeCycle) +"没有抄表记录");
        }
        return result;
    }


    @Override
    public BigDecimal computePrivateSummary(NyCheckMeter nyCheckMeter) {
        //查询 是否存在计算结果，有直接返回，没有计算，返回计算，结果
        //汇总记录总表id
        NyMeterAccount2 nyMeterAccount = new NyMeterAccount2();
        nyMeterAccount.setId(nyCheckMeter.getMeterId());
        //查询总表树
        NyMeterAccountVO nyMeterAccountVO = nyMeterAccountManager.selectRoot(nyCheckMeter.getMeterId());
        //查询总表树下的私表
        List<NyMeterAccountVO> privates = nyMeterAccountManager.selectPrivateLeafs(nyMeterAccountVO);

        Date feeCycle = nyCheckMeter.getFeeCycle();
        //查询抄表记录，累积 实际用电量
        BigDecimal result = new BigDecimal("0");
        for(NyMeterAccountVO account:privates){
            String privateid = account.getId();
            NyCheckMeter nyCheckMeter1 = this.selectNyCheckMeterByIdAndFeeCycle(account.getId(),nyCheckMeter.getFeeCycle());
            if(nyCheckMeter1 != null){
                result = result.add(nyCheckMeter1.getActualDosage());
            }
        }
        //返回更新结果
        return result;
    }

    private AjaxResult selectCheckSumTree(NyCheckMeterVO nyCheckMeterVO){
        //记录未抄表记录
        StringBuilder failureMsg = new StringBuilder();
        //总表汇总计算记录
        NyCheckSumVO result = new NyCheckSumVO();
        result.setPid("0");
        //构建汇总记录树
        copyBeanCheckSumVOPlus(nyCheckMeterVO,result,failureMsg);
        log.info("汇总记录：\n" + result.getPrivateSum());
        return AjaxResult.success(failureMsg.toString(),result);
    }

    private void copyBeanCheckSumVOPlus(NyCheckMeterVO nyCheckMeterVO,NyCheckSumVO nyCheckSumVO,StringBuilder failureMsg){
        //构建汇总记录节点
        BeanUtil.copyProperties(nyCheckMeterVO,nyCheckSumVO, CopyOptions.create().setIgnoreProperties("children"));
        nyCheckSumVO.setId(IdUtil.getSnowflake(0, 0).nextIdStr());
        //检测抄表记录节点是否抄表
        if(nyCheckMeterVO.getActualDosage() == null){
            nyCheckSumVO.setActualDosage(new BigDecimal("0"));
            failureMsg.append("<br/>" + nyCheckMeterVO.getMeterType() + nyCheckMeterVO.getMeterNum()+ nyCheckMeterVO.getEnterpriseName()  + " 未抄表");
        }
        if (nyCheckMeterVO.getChildren() ==null || nyCheckMeterVO.getChildren().size() == 0){
            if(nyCheckMeterVO.getCategory().equals("私表")){
                nyCheckSumVO.setPrivateSum(nyCheckSumVO.getActualDosage());
            }
            return;
        }

        List<NyCheckMeterVO> children = nyCheckMeterVO.getChildren();
        for(int i=0;i<children.size();i++){
            NyCheckMeterVO child = children.get(i);
            NyCheckSumVO nyCheckSumVO1 = new NyCheckSumVO();
            nyCheckSumVO1.setPid(nyCheckSumVO.getId());
            copyBeanCheckSumVOPlus(child,nyCheckSumVO1,failureMsg);
            nyCheckSumVO.getChildren().add(nyCheckSumVO1);

        }
        //私表汇总量
        for(NyCheckSumVO child:nyCheckSumVO.getChildren()){
            nyCheckSumVO.setPrivateSum(nyCheckSumVO.getPrivateSum().add(child.getPrivateSum()));
        }
        //计算查值
        nyCheckSumVO.setDiffValue(nyCheckSumVO.getActualDosage().subtract(nyCheckSumVO.getPrivateSum()));

    }

    public int computeNyMeterSummaryAll(NyCheckMeter nyCheckMeter){
        Date feeCycle = nyCheckMeter.getFeeCycle();
        int results = 0;
        if(feeCycle == null){
            return 0;
        }else{
            nyCheckMeter.setCategory(NyMeterCategoryEnum.总表.getCode());
            List<NyCheckMeter> meterList = this.selectNyCheckMeterList(nyCheckMeter);
            for(int i =0;i<meterList.size();i++){
                results += (computeNyMeterSummary(meterList.get(i)));
            }
        }
        return results;
    }

    public AjaxResult computeNyMeterSummaryAllPlus(NyCheckMeter nyCheckMeter){

        Date feeCycle = nyCheckMeter.getFeeCycle();
        List<NyCheckSumVO> results = new ArrayList<>();
        StringBuilder builder = new StringBuilder();
        nyCheckMeter.setCategory(NyMeterCategoryEnum.总表.getCode());
        List<NyCheckMeter> meterList = this.selectNyCheckMeterList(nyCheckMeter);
        //查询单个总表
        if(StringUtils.isNotBlank(nyCheckMeter.getMeterNum())){
            //总表没有抄录记录
            if(meterList.size() ==0){
                builder.append(nyCheckMeter.getMeterNum()).append(" ").append(DateUtils.parseDateToStr(DateUtils.YYYY_MM,nyCheckMeter.getFeeCycle())).append("未抄录无法计算");
                return AjaxResult.success(builder.toString(),results);
            }
            AjaxResult result = computeNyMeterSummaryPlus(meterList.get(0));
            results.add((NyCheckSumVO)result.get(AjaxResult.DATA_TAG));
            builder.append(result.get(AjaxResult.MSG_TAG));
        }else{
            //A\B园区所有总表
            //查询总表台账，添加builder
            List<NyMeterAccount2> accountList = this.selectNyAccountByMeter(nyCheckMeter);
            //比较总表抄表记录，进行比对查找总表遗漏，
            String sb = getSubtract(accountList,meterList);
            if(sb != null){
                builder.append(sb);
            }
            for(int i =0;i<meterList.size();i++){
                AjaxResult result = computeNyMeterSummaryPlus(meterList.get(i));
                results.add((NyCheckSumVO)result.get(AjaxResult.DATA_TAG));
                builder.append(result.get(AjaxResult.MSG_TAG));
            }
        }

        return AjaxResult.success(builder.toString(),results);
    }

    @Override
    public Boolean getIsCompleted(NyCheckMeter nyCheckMeter) { ;
        NyCheckSum nyCheckSum = new NyCheckSum();
        nyCheckSum.setFeeCycle(nyCheckMeter.getFeeCycle());
        nyCheckSum.setParkNum(nyCheckMeter.getParkNum());
        List<NyCheckSum> list = nyCheckSumMapper.selectNyCheckSumList(nyCheckSum);
        return list.size()>0?true:false;
    }

    @Override
    public NyCheckMeterVO selectNyMeterCheckVO(NyCheckMeter nyCheckMeter) {
        // meterId,feeCycle
        String meterId = nyCheckMeter.getMeterId();
        //查询总表树
        NyMeterAccountVO nyMeterAccountVO = nyMeterAccountManager.selectRoot(meterId);
        //查询总表记录树
        NyCheckMeterVO nyCheckMeterVO = nyMeterAccountManager.selectCheckMeterTree(nyMeterAccountVO,nyCheckMeter.getFeeCycle());
        return nyCheckMeterVO;
    }

    //meterType,parkNum
    /*
    * 根据园区，类型，当前时间，选择总表抄表记录，根据费用周期分组，组内累加；
    * */
    @Override
    public Map<String, BigDecimal> energyTrend(NyCheckMeter nyCheckMeter) {
        Map<String, BigDecimal> resultMap = new LinkedHashMap<>();
        nyCheckMeter.setCategory("总表");
        //水表，电表 月度总额
        List<NyCheckMeter>  list = nyCheckMeterMapper.selectNyCheckMeterSumGroupMonth(nyCheckMeter);
        for(NyCheckMeter checkMeter:list){
            resultMap.put(DateUtils.getMonth(nyCheckMeter.getFeeCycle()),nyCheckMeter.getActualDosage());
        }
        return resultMap;
    }

    /**
     *
     * @param parkNum,Feecycle,meterType
     * @return group by 企业
     */
    @Override
    public List<NyCheckMerBPVO> energyRecord(NyCheckMeter nyCheckMeter) {
        List<NyCheckMerBPVO> resultList = new ArrayList<>();
        //查询电表
        nyCheckMeter.setMeterType("电表");
        List<NyCheckMeter> elList = nyCheckMeterMapper.selectNyCheckMeterSumGroupEn(nyCheckMeter);
        for(NyCheckMeter el:elList){
            if(StringUtils.isNotBlank(el.getEnterpriseId())){
                NyCheckMerBPVO nyCheckMerBPVO = new NyCheckMerBPVO();
                BeanUtils.copyBeanProp(el,nyCheckMerBPVO);
                nyCheckMerBPVO.setElActualDosage(el.getActualDosage());
                resultList.add(nyCheckMerBPVO);
            }

        }
        //list转map ,a2.enterprise_name,a2.enterprise_id
        Map<String,NyCheckMerBPVO> enterMap = resultList.stream().collect(Collectors.toMap(o->(o.getEnterpriseId()),a->a));
//        Map<String,NyCheckMerBPVO>
        //查询水表
        nyCheckMeter.setMeterType("水表");
        List<NyCheckMeter> waterList = nyCheckMeterMapper.selectNyCheckMeterSumGroupEn(nyCheckMeter);
        //list 转 map<enterid,NyCheckMerBPVO>;enterid ，存在，设置水表数据；
        //合并结果集
        for(NyCheckMeter wa:waterList){
            if(StringUtils.isNotBlank(wa.getEnterpriseId())){
                if(enterMap.containsKey(wa.getEnterpriseId())){
                    enterMap.get(wa.getEnterpriseId()).setWaterActualDosage(wa.getActualDosage());
                }else {
                    NyCheckMerBPVO nyCheckMerBPVO = new NyCheckMerBPVO();
                    BeanUtils.copyBeanProp(wa,nyCheckMerBPVO);
                    nyCheckMerBPVO.setWaterActualDosage(wa.getActualDosage());
                    resultList.add(nyCheckMerBPVO);
                }

            }
        }

        return resultList;
    }

    @Override
    public String computeSum(String parkNum, String meterType, Date fee_cycle) {
        Map<String, BigDecimal> resultMap = new LinkedHashMap<>();
        NyCheckMeter nyCheckMeter = new NyCheckMeter();
        nyCheckMeter.setCategory("私表");
        nyCheckMeter.setMeterType(meterType);
        nyCheckMeter.setParkNum(parkNum);
        nyCheckMeter.setFeeCycle(fee_cycle);
        //水表，电表 月度总额
        NyCheckMeter  list = nyCheckMeterMapper.selectSumGroupMonth(nyCheckMeter);
        if(list != null ){
            return list.getActualDosage().toString();
        }
        return null;
    }


    private List<NyMeterAccount2> selectNyAccountByMeter(NyCheckMeter nyCheckMeter) {
        NyMeterAccount2 account2 = new NyMeterAccount2();
        account2.setParkId(nyCheckMeter.getParkId());
        account2.setCategory(NyMeterCategoryEnum.总表.getCode());
        account2.setMeterType(nyCheckMeter.getMeterType());
        account2.setParkNum(nyCheckMeter.getParkNum());
        return nyMeterAccount2Mapper.selectNyMeterAccount2List(account2);
    }

    //获取两个集合的差集 list1 - 交集
    private String getSubtract(List<NyMeterAccount2> list1,List<NyCheckMeter> list2){
        if(list1.size() == list2.size()){
            return null;
        }else {
            for(NyCheckMeter nyCheckMeter:list2){
                for(int i =0;i<list1.size();i++){
                    if(list1.get(i).getId().equals(nyCheckMeter.getMeterId())){
                        list1.remove(i);
                        continue;
                    }
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        sb.append("总表：");
        for(NyMeterAccount2 account2:list1){
            sb.append(account2.getMeterNum()+" ");
        }
        sb.append("未抄表<br/>");
        return sb.toString();
    }

    private AjaxResult computeNyMeterSummaryPlus(NyCheckMeter nyCheckMeter){
        Date feeCycle = nyCheckMeter.getFeeCycle();
        String meterId = nyCheckMeter.getMeterId();
        //查询汇总记录
        //NyCheckSum nyCheckSum = nyCheckSumService.selectNyCheckSum(nyCheckMeter);

        //查询总表树
        NyMeterAccountVO nyMeterAccountVO = nyMeterAccountManager.selectRoot(meterId);
        //构建抄表记录树
        NyCheckMeterVO nyCheckMeterVO = nyMeterAccountManager.selectCheckMeterTree(nyMeterAccountVO,feeCycle);

        //计算汇总量
        AjaxResult result = selectCheckSumTree(nyCheckMeterVO);

        return result;
    }
    //递归
    private void setNyCheckSumVO(NyCheckSumVO result ){
        result.setId(IdUtil.getSnowflake(0, 0).nextIdStr());
        List<NyCheckSumVO> children = result.getChildren();
        if(children == null || children.size()<= 0)
            return;
        for(NyCheckSumVO res:children){
            setNyCheckSumVO(res);
        }
    }

    @Override
    public int computeNyMeterSummary(NyCheckMeter nyCheckMeter){
        Date feeCycle = nyCheckMeter.getFeeCycle();
        String meterId = nyCheckMeter.getMeterId();
        //查询汇总记录
        NyCheckSum nyCheckSum = nyCheckSumService.selectNyCheckSum(nyCheckMeter);
        if(nyCheckSum != null){
            // 返回 buildNyCheckSumVO
            //return buildNyCheckSumVO(nyCheckSum.getId());
            return 1;
        }
        //计算汇总量
        //查询总表下的私表
        NyMeterAccountVO nyMeterAccountVO = nyMeterAccountManager.selectRoot(meterId);
        if(nyMeterAccountVO != null){
            //查询抄表记录
            NyCheckMeterVO nyCheckMeterVO = nyMeterAccountManager.selectCheckMeterTree(nyMeterAccountVO,feeCycle);
            AjaxResult result = selectCheckSumTree(nyCheckMeterVO);
            NyCheckSumVO test = (NyCheckSumVO) result.get(AjaxResult.DATA_TAG);
            //插入总表计算结果
            return nyCheckSumService.insertComputeLog(test);
        }else {
            return 0;
        }

        //return result;
    }

    /*计算私表汇总量*/
    @Override
    public int computeNyMeterSummary(String id) {
        //查询总表抄表记录
        NyCheckMeter nyCheckMeter = nyCheckMeterMapper.selectNyCheckMeterById(id);
        return computeNyMeterSummary(nyCheckMeter);
    }

    //
    private NyCheckSum insertNyCheckSum(NyCheckMeter nyCheckMeter,BigDecimal result){
        //更新分摊池
        //插入nyCheckSum
        NyCheckSum nyCheckSum = new NyCheckSum();
        nyCheckSum.setMeterId(nyCheckMeter.getMeterId());
        nyCheckSum.setFeeCycle(nyCheckMeter.getFeeCycle());
        nyCheckSum.setPrivateSum(result);
        nyCheckSum.setDiffValue(nyCheckMeter.getActualDosage().subtract(result));
        nyCheckSum.setIsComputed("1");
        nyCheckSumService.insertNyCheckSum(nyCheckSum);
        NyMeterAccount2 nyMeterAccount2 = nyMeterAccount2Service.selectNyMeterAccount2ById(nyCheckMeter.getMeterId());
        BigDecimal res = nyMeterAccount2.getShareInitialValue().add(nyCheckSum.getDiffValue());
        nyMeterAccount2.setShareInitialValue(res);
        nyMeterAccount2Service.updateNyMeterAccount2(nyMeterAccount2);
        return nyCheckSum;
    }


    private NyCheckSumVO buildNyCheckSumVO(String id){
        NyCheckSumVO result = nyCheckSumService.selectRootById(id);
        return result;
    }
}
